#region Imported Namespaces
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Data;
using PHSRAG.Utility;

using Policy = PHSRAG.Insight21.Policy;
#endregion

namespace PHSRAG.Insight21.InsightWebControls
{
	#region Class RefreshDates
	/// <summary>
	/// RefreshDates makes the last gl post date, last PO/AP post date, and the last salary post 
	/// date available to a page through its public properties.  These dates can optionally be made visible
	/// or invisible on the page.
	/// </summary>
	/// <remarks>
	/// Any page which would like to use a refresh date should include this control on the page.
	/// The visibility of the dates may be set either at design time (in HTML) or at runtime (through the instance).
	/// </remarks>
	/// <example>
	/// The following example shows how the page would use this control. The registration of the control can be done
	/// simply by dropping the control on the page in design mode.
	/// <code>
	/// <![CDATA[
	/// <%@ Register TagPrefix="cc1" Namespace="PHSRAG.Insight21.InsightWebControls" Assembly="PHSRAG.Insight21.InsightWebControls" %>
	/// ...
	/// <body>
	/// ...
	/// <cc1:refreshdates id="refreshDates" runat="server" GLAsOfDateVisible="True" POAPAsOfDateVisible="True" SalaryAsOfDateVisible="True" />
	/// ...
	/// </body>
	/// ]]>
	/// </code>
	/// </example>
	[ToolboxData("<{0}:RefreshDates runat=server />"), Designer(typeof(RefreshDatesDesigner))]
	public class RefreshDates : System.Web.UI.WebControls.WebControl, INamingContainer
	{
		#region Constants
		private const string RefreshDatesControlKey	= "RefreshDates_D511306A-23E5-4d9b-AC38-17A2DEC0F6AE";
		#endregion

		#region Instance Variables
		private	Policy.ICachePolicy	cachePolicy;
		private Label				glPostAsOfDateLabel;
		private Label				poapAsOfDateLabel;
		private Label				salaryAsOfDateLabel;
		private Label				glPostAsOfDate;
		private Label				poapAsOfDate;
		private Label				salaryAsOfDate;
        private Label               patientCareAsOfDateLabel;
        private Label               patientCareAsOfDate;
		#endregion

		#region Private Properties
		private static bool IsDesignMode
		{
			get { return HttpContext.Current == null; }
		}
		#endregion
		#region Public Properties
		/// <summary>
		/// Gets the date of the last GL post.
		/// </summary>
		[Category("Data"), Description("Gets the date of the last GL post.")]
		public DateTime GLPostAsOfDate
		{
			get {EnsureChildControls(); 
				return (IsDesignMode) ? 
					Convert.ToDateTime("01/01/1900") : 
					(DateTime) ((DataSet)cachePolicy.GetCachedObject(RefreshDatesControlKey)).Tables[0].Rows[0]["glPostAsOfDate"];}
		}
		
		/// <summary>
		/// Gets the date of the last salary post.
		/// </summary>
		[Category("Data"), Description("Gets the date of the last salary post.")]
		public DateTime SalaryAsOfDate
		{
			get {EnsureChildControls(); 
				return (IsDesignMode) ? 
					Convert.ToDateTime("01/01/1900")  : 
					(DateTime) ((DataSet)cachePolicy.GetCachedObject(RefreshDatesControlKey)).Tables[0].Rows[0]["salaryAsOfDate"];}
		}
		
		/// <summary>
		/// Gets the date of the last PO/AP post.
		/// </summary>
		[Category("Data"), Description("Gets the date of the last PO/AP post.")]
		public DateTime POAPAsOfDate
		{
			get {EnsureChildControls(); 
				return (IsDesignMode) ? 
					Convert.ToDateTime("01/01/1900")  : 
					(DateTime) ((DataSet)cachePolicy.GetCachedObject(RefreshDatesControlKey)).Tables[0].Rows[0]["poapAsOfDate"];}
		}

        /// <summary>
        /// Gets the date of the last Patient Care post.
        /// </summary>
        [Category("Data"), Description("Gets the date of the last Patient Care post.")]
        public DateTime PatientCareAsOfDate
        {
            get
            {
                EnsureChildControls();
                return (IsDesignMode) ?
                    Convert.ToDateTime("01/01/1900") :
                    (DateTime)((DataSet)cachePolicy.GetCachedObject(RefreshDatesControlKey)).Tables[0].Rows[0]["patientCareAsOfDate"];
            }
        }
        
        /// <summary>
		/// Makes the last PO/AP post date visible on the page.
		/// </summary>
		[Category("Appearance"), Description("Make the date of the last PO/AP post visible.")]
		public bool POAPAsOfDateVisible
		{
			get {EnsureChildControls(); return poapAsOfDate.Visible;}
			set {EnsureChildControls(); poapAsOfDate.Visible = poapAsOfDateLabel.Visible = value;}
		}
		
		/// <summary>
		/// Makes the last Salary post date visible on the page.
		/// </summary>
		[Category("Appearance"), Description("Make the date of the last Salary post visible.")]
		public bool SalaryAsOfDateVisible
		{
			get {EnsureChildControls(); return salaryAsOfDate.Visible;}
			set {EnsureChildControls(); salaryAsOfDate.Visible = salaryAsOfDateLabel.Visible = value;}
		}
		
		/// <summary>
		/// Makes the last GL post date visible on the page.
		/// </summary>
		[Category("Appearance"), Description("Make the date of the last GL post visible.")]
		public bool GLAsOfDateVisible
		{
			get {EnsureChildControls(); return glPostAsOfDate.Visible;}
			set {EnsureChildControls(); glPostAsOfDate.Visible = glPostAsOfDateLabel.Visible = value;}
		}

        /// <summary>
        /// Makes the Patient Care post date visible on the page.
        /// </summary>
        [Category("Appearance"), Description("Make the date of the last Patient Care post visible.")]
        public bool PatientCareAsOfDateVisible
        {
            get { EnsureChildControls(); return patientCareAsOfDate.Visible; }
            set { EnsureChildControls(); patientCareAsOfDate.Visible = patientCareAsOfDateLabel.Visible = value; }
        }
        #endregion

		#region Overrides
		/// <summary>
		/// Create all controls. Notice that the creation is more than just instantiating the controls. 
		/// It also involves generating the underlying HTML so that the controls show up per the need.
		/// </summary>
		protected override void CreateChildControls()
		{
			CreateControls();
			GenerateControlTree();
		}

		/// <summary>
		/// Render the control. Note that we simply ensure that all child controls are created, and then 
		/// delegate the call back to the base class.
		/// </summary>
		/// <param name="writer">The writer to use for rendering</param>
		protected override void Render(HtmlTextWriter writer)
		{
			EnsureChildControls();
			base.Render(writer);
		}
		
		/// <summary>
		/// Loads the date of the last refresh for GL Post, Salary Post and
		///	PO/AP Post on the page.
		/// </summary>
		/// <param name="e">Arguments associated with the event.</param>
		protected override void OnInit(EventArgs e)
		{
			cachePolicy = (Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey];
			EnableViewState = false;
			
			// Normally, the following code should only be done from when the Load event
			// fires and onward. However, since many pages use the GLPostAsOfDate as a
			// parameter to retrieve data prior to that event, the control must be fully
			// initialized now.
			GetRefreshDates();
			EnsureChildControls();
			glPostAsOfDate.Text = (GLPostAsOfDate.ToShortDateString()=="1/1/1900" ) ? "ERROR" : GLPostAsOfDate.ToShortDateString();
			poapAsOfDate.Text = (POAPAsOfDate.ToShortDateString()=="1/1/1900" ) ? "ERROR" : POAPAsOfDate.ToShortDateString();
			salaryAsOfDate.Text = (SalaryAsOfDate.ToShortDateString()=="1/1/1900" ) ? "ERROR" : SalaryAsOfDate.ToShortDateString();
            patientCareAsOfDate.Text = (PatientCareAsOfDate.ToShortDateString() == "1/1/1900") ? "ERROR" : PatientCareAsOfDate.ToShortDateString();
        }
		#endregion

		#region Private Methods
		/// <summary>
		/// Create all controls in the RefreshDates.
		/// </summary>
		private void CreateControls()
		{
			Controls.Clear();

			glPostAsOfDate = new Label();
			glPostAsOfDate.ID = "glPostAsOfDate";
			glPostAsOfDate.Text = "mm/dd/yyyy";
			glPostAsOfDate.Visible = false;

			poapAsOfDate = new Label();
			poapAsOfDate.ID = "poapAsOfDate";
			poapAsOfDate.Text = "mm/dd/yyyy";
			poapAsOfDate.Visible = false;
			
			salaryAsOfDate = new Label();
			salaryAsOfDate.ID = "salaryAsOfDate";
			salaryAsOfDate.Text = "mm/dd/yyyy";
			salaryAsOfDate.Visible = false;

			glPostAsOfDateLabel = new Label();
			glPostAsOfDateLabel.ID = "glPostAsOfDateLabel";
			glPostAsOfDateLabel.Text = "Last GL Post:";
			glPostAsOfDateLabel.Visible = false;
			
			poapAsOfDateLabel = new Label();
			poapAsOfDateLabel.ID = "poapAsOfDateLabel";
			poapAsOfDateLabel.Text = "Last PO/AP Post:";
			poapAsOfDateLabel.Visible = false;
			
			salaryAsOfDateLabel = new Label();
			salaryAsOfDateLabel.ID = "salaryAsOfDateLabel";
			salaryAsOfDateLabel.Text = "Last Salary Post:";
			salaryAsOfDateLabel.Visible = false;

            patientCareAsOfDateLabel = new Label();
            patientCareAsOfDateLabel.ID = "patientCareAsOfDateLabel";
            patientCareAsOfDateLabel.Text = "Last Patient Care Post:";
            patientCareAsOfDateLabel.Visible = false;

            patientCareAsOfDate = new Label();
            patientCareAsOfDate.ID = "patientCareAsOfDate";
            patientCareAsOfDate.Text = "mm/dd/yyyy";
            patientCareAsOfDate.Visible = false;
        }

		/// <summary>
		/// Setup the control tree to reflect the actual (and exact) layout of the controls within RefreshDates.
		/// </summary>
		private void GenerateControlTree()
		{
			Controls.Add(new LiteralControl(
				"\n<table class=\"RefreshDatesContainer\" border=\"0\" bordercolor=\"red\">\n" +
				"\t<tr>\n" +
				"\t\t<td align=\"right\">" +
				"<table class=\"RefreshDates\" border=\"0\" bordercolor=\"red\">\n" +
				"\t<tr>\n" +
				"\t\t<td align=\"right\">"));

			Controls.Add(glPostAsOfDateLabel);			
			Controls.Add(new LiteralControl("&nbsp;</td>\n\t\t<td colspan=\"1\">"));
			Controls.Add(glPostAsOfDate);

			Controls.Add(new LiteralControl(
				"&nbsp;&nbsp;</td>\n" + 
				"\t\t<td align=\"right\">"));
					
			Controls.Add(poapAsOfDateLabel);
			Controls.Add(new LiteralControl("&nbsp;</td>\n\t\t<td>"));
			Controls.Add(poapAsOfDate);

			Controls.Add(new LiteralControl(
				"&nbsp;&nbsp;</td>\n" + 
				"\t\t<td align=\"right\">"));

			Controls.Add(salaryAsOfDateLabel);
			Controls.Add(new LiteralControl("&nbsp;</td>\n\t\t<td colspan=\"1\">\n"));
			Controls.Add(salaryAsOfDate);

            Controls.Add(new LiteralControl(
                "&nbsp;&nbsp;</td>\n" +
                "\t\t<td align=\"right\">"));

            Controls.Add(patientCareAsOfDateLabel);
            Controls.Add(new LiteralControl("&nbsp;</td>\n\t\t<td colspan=\"1\">\n"));
            Controls.Add(patientCareAsOfDate);
            
            Controls.Add(new LiteralControl(
				"&nbsp;&nbsp;</td>\n" +
				"\t\t\t\t</tr>\n" +
				"\t\t\t</table>" +
				"\t\t</td>\n" +
				"\t</tr>\n" +
				"</table>"));
		}

		/// <summary>
		/// Loads the date of the last refresh for GL Post, Salary Post and
		///	PO/AP Post into the session cache.
		/// </summary>
		private void GetRefreshDates()
		{
			DataSet ds = cachePolicy.GetCachedObject(RefreshDatesControlKey) as DataSet; 
			if (ds == null)
			{
				ds = DataAccess.GetDataSet(Utility.DataAccess.GetConnectionString(), "GetRefreshDates");
				cachePolicy.Cache(RefreshDatesControlKey, ds);
			}
		}
		#endregion

		#region Internal Methods
		/// <summary>
		/// This method is ONLY invoked by the associated designer to show the control contents at design time.
		/// </summary>
		internal void Design()
		{
			EnsureChildControls();
		}
		#endregion
	}
	#region Class RefreshDatesDesigner
	/// <summary>
	/// Designer associated with the RefreshDates control.
	/// </summary>
	/// <remarks>
	/// This class cannot be used directly.
	/// </remarks>
	public class RefreshDatesDesigner : ControlDesigner
	{
		#region Overrides
		/// <summary>
		/// Force the control to create its child controls for display at design time.
		/// </summary>
		/// <returns>HTML representation of the control</returns>
		public override string GetDesignTimeHtml()
		{
			((RefreshDates)Component).Design();
			return base.GetDesignTimeHtml();
		}
		#endregion
	}
	#endregion
}

#endregion
